package com.liangzong.betspider.task;


import com.google.common.collect.Lists;
import com.liangzong.betspider.Exceptions.NoOtherMatchException;
import com.liangzong.betspider.config.ChromeDriverConfig;
import com.liangzong.betspider.utils.DriverUtil;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.liangzong.betspider.utils.DriverUtil.gotoMatchListPage;
import static com.liangzong.betspider.utils.ProcessDataUtil.getStrByReg;
import static com.liangzong.betspider.utils.SpiderInfoUtil.*;

@Slf4j
public class CycleTask extends Thread {
    WebDriver driver;
    private final static String emptyPage = "data:,";

    private final static String newTab = "chrome://new-tab-page/";
    private final static String listPage = "IP/B1";
    private final static String matchListPage = "IP/EV";
    private final static String HOME = "https://www.365365304.com/#/IP/B1";
    private long pauseTime;
    private int overTime;
    private int port;
    private boolean reverse;
    private volatile boolean stop;
    private boolean stoped;
    String sessionId;
    ChromeDriverConfig chromeDriverConfig;


    CycleTask(String sessionId, WebDriver driver, long pauseTime, boolean reverse, ChromeDriverConfig chromeDriverConfig, int port) {
        this.driver = driver;
        this.pauseTime = pauseTime;
        this.reverse = reverse;
        this.sessionId = sessionId;
        this.chromeDriverConfig = chromeDriverConfig;
        this.port = port;
    }

    public void stopCycleTask() {
        log.info("设置CycleTask 停止工作");
        this.stop = true;
    }


    @Override
    public void run() {
        //已执行轮数数 间隔多少轮后刷新
        int cycleTimes = 0;
        int duringTimes = 10;
        int duringTime = 10;
        boolean isFirstTime = true;
        WebElement footballMenu = null;
        LocalDateTime start = LocalDateTime.now();
        LocalDateTime now = start.plusMinutes(10);
        do {
            try {
                now = LocalDateTime.now();
                long toMinutes = Duration.between(start, now).toMinutes();
                if (cycleTimes != 0 && cycleTimes % duringTimes == 0 && toMinutes>=duringTime) {
                    log.info("第{} 开始刷新", cycleTimes / duringTimes);
                    //
                    isFirstTime = refresh();
                    start = LocalDateTime.now();
                    pause();

                }
                log.info("开始下一轮-------driver.getCurrentUrl()=" + driver.getCurrentUrl() + "-------------------------------------------------------------------------------------------------------");
                if (driver.getCurrentUrl().indexOf(matchListPage) == -1) {

                    if (driver.getCurrentUrl().indexOf(listPage) != -1) {
                        gotoMatchListPage(driver, isFirstTime);
                    } else if (driver.getCurrentUrl().equals(emptyPage) || driver.getCurrentUrl().equals(newTab)) {
                        refresh();
                        pause(10 * 1000L);
                        continue;
                    }
                } else {
                    //如果需要刷新
                    if (getRefreshState(sessionId)) {
                        refresh();
                        updateRefreshStateSuccess(sessionId);
                        pause(10 * 1000l);
                    } else if (needToRefresh(sessionId)) {
                        refresh();
                        pause(10 * 1000l);
                        break;
                    }
                }
                isFirstTime = false;
                clearTimeInfo();

                if (footballMenu == null) {
                    footballMenu = findMenu();
                }
                openMatch(footballMenu);

            } catch (NoOtherMatchException e) {
                //设置菜单为空 重新获取
                footballMenu = null;
                driver.get(HOME);
                pause(20 * 1000L);
                log.error(e.getMessage(), e);
                continue;
            } catch (Exception e) {
                //设置菜单为空 重新获取
                footballMenu = null;
                log.error(e.getMessage(), e);
            }
            cycleTimes++;
            pause(2 * 1000L);
        } while (!stop);
        log.info("CycleTask 已结束工作");
        stoped = true;
    }

    public boolean isStoped() {
        return stoped;
    }

    public WebElement findMenu() {
        WebElement openedClz = driver.findElement(By.cssSelector("div[class='ipn-Classification ipn-Classification-open '"));
        WebElement label = openedClz.findElement(By.cssSelector("span[class='ipn-ClassificationButton_Label ']"));
        if (label.getText().indexOf("足球") != -1) {
            return openedClz;
        }
        return null;
    }

    private boolean refresh() {
        String currentWindow = null;
        try {
            currentWindow = driver.getWindowHandle();
        } catch (Exception e) {
            Set<String> windowHandles = driver.getWindowHandles();
            for (String win : windowHandles) {
                if (win.indexOf(matchListPage) == -1 || win.indexOf(listPage) != -1) {
                    driver.switchTo().window(win);
                    currentWindow = win;
                    break;
                }
            }
        }

        //关闭老窗口
        Set<String> windowHandles = driver.getWindowHandles();

        for (String win : windowHandles) {
            if (!win.equals(currentWindow)) {
                driver.switchTo().window(win);
                pause();
                driver.close();
            }
        }
        driver.switchTo().window(currentWindow);
        //打开新窗口
        DriverUtil.open(this.port);
        pause();

        windowHandles = driver.getWindowHandles();
        List<String> collect = windowHandles.stream().collect(Collectors.toList());
        String newWindow = null;

        if (windowHandles.size() > 1) {
            for (String win : windowHandles) {
                if ((win.indexOf(matchListPage) == -1 || win.indexOf(listPage) != -1) && !win.equals(currentWindow)) {
                    newWindow = win;
                    driver.switchTo().window(win);
                }
            }
        }else {
            newWindow = collect.get(0);
        }
        windowHandles = driver.getWindowHandles();
        for (String win : windowHandles) {
            driver.switchTo().window(win);
            if (!win.equals(newWindow)) {
                driver.close();
            }
            pause();
        }
        driver.switchTo().window(newWindow);
        return true;
    }


    private void openMatch(WebElement footballMenu) {
        if (footballMenu == null) {
            return;
        }
        List<WebElement> closedClassifications = footballMenu.findElements(By.cssSelector("div[class^='ipn-Competition ipn-Competition-closed ']"));
        List<WebElement> openedClassifications = footballMenu.findElements(By.cssSelector("div[class^='ipn-Competition ']"));

        //点开所有地区联赛
        for (WebElement element1 : closedClassifications) {
            if (element1.getText().indexOf("足球电竞") != -1) {
                if (!openedClassifications.isEmpty()) {
                    log.info("已经打开联赛菜单，不再打开电竞菜单");
                    continue;
                }
            }
            element1.click();
        }
        List<WebElement> fixture_Wrapper = footballMenu.findElements(By.cssSelector("div[class='ipn-Fixture_Wrapper']"));
        putNumOfElement(fixture_Wrapper.size());
        //轮流点击所有比赛
        int i = 0;
        //如果从后往前遍历
        if (reverse) {
            fixture_Wrapper = Lists.reverse(fixture_Wrapper);
        }
        for (WebElement element1 : fixture_Wrapper) {

            try {
                if (stop) {
                    return;
                }
                if (element1.isEnabled()) {
                    if (i != 0 && i % 10 == 0) {
                        ((RemoteWebDriver) driver).executeScript("arguments[0].scrollIntoView();", element1);
                    }
                    WebElement timeElement = element1.findElement(By.className("ipn-Fixture_TimerContainer"));
                    String time = timeElement.getText();
                    element1.click();
                    String currentUrl = driver.getCurrentUrl();
                    String url = getStrByReg(currentUrl, "EV(\\d.*?)C1");
                    putTimeInfo(url, time);
                }
            } catch (ElementClickInterceptedException e) {
                log.error(e.getMessage());
            } catch (StaleElementReferenceException e) {
                log.error(e.getMessage());
            } catch (Exception e) {
                throw e;
            }

            i++;
            pause(pauseTime);
        }
        clearTimeInfo();

    }

    private static void pause() {
        pause(5 * 1000L);
    }

    private static void pause(Long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

